<script setup lang="ts">
import YkPagination from '@yk/components/pagination/YkPagination.vue'
import { Pages } from '@typings/pages'
import { Download } from '@element-plus/icons-vue'
import YkDatePicker from '@yk/components/date-picker/YkDatePicker.vue'
import { TableUtil } from '@utils/table-util'
import { getDeviceListAPI } from '@/api/device'
import { DeviceDTO } from '@/api/entity/device'
import { getVariableListByModelAPI } from '@/api/variable'
import { VariableDTO } from '@/api/entity/variable'
import { exportReportByVarIdsAPI, getExportReportListByPageAPI } from '@/api/report'
import { ElForm, ElTable } from 'element-plus'
import { required } from '@utils/form-rule'
import { ExcelHistoryDTO } from '@/api/entity/report'
import settings from '@/settings'

defineOptions({ name: 'CustomReport' })

onMounted(() => {
  getDeviceList()
  getTableData()
})

onActivated(() => {
  tableDataRef.value.doLayout()
})

const activeName = ref('Custom')

watch(activeName, () => {
  if (activeName.value === 'Export') {
    getTableData()
  }
})

// region TODO 自定义报表
const constructionForm = ref({
  excelName: '',
  device: [] as string[],
  startTime: '',
  endTime: '',
  vars: [] as string[]
})
const constructionFormRef = ref<InstanceType<typeof ElForm>>()
const constructionFormRules = {
  excelName: [required('报表名称为必填项')],
  device: [required.change('设备为必填项')],
  startTime: [required.change('数据时间为必填项')],
  vars: [required.change('数据维度为必填项')]
}

// region TODO 设备列表
const deviceList = shallowRef<DeviceDTO[]>([])
// 设备 - 模板字典 Map<设备id, DeviceDTO>
const deviceMap = new Map<string, DeviceDTO>()
function deviceChangeHandle () {
  const deviceId = constructionForm.value.device[0]
  variableTemplateId.value = deviceId ? deviceMap.get(deviceId).templateId : null
  generateReportStructure()
}
function getDeviceList () {
  deviceMap.clear()
  getDeviceListAPI().then((res) => {
    res.result().then((rdata) => {
      deviceList.value = rdata.data
      deviceList.value.forEach((item) => {
        if (item.templateId) {
          deviceMap.set(item.id, item)
        }
      })
    })
  })
}
// endregion

// region TODO 变量模板
const variableTemplateId = ref(null)
watch(variableTemplateId, () => {
  constructionForm.value.vars = []
  variableMap.clear()
  variableList.value = []
  getVariableList()
})
// endregion

// region TODO 变量列表
const variableList = shallowRef<VariableDTO[]>([])
// 变量列表字典Map<变量id, VariableDTO>
const variableMap = new Map<string, VariableDTO>()
function variableChangeHandle () {
  generateReportStructure()
}
function getVariableList () {
  if (!variableTemplateId.value) return
  getVariableListByModelAPI({
    templateId: variableTemplateId.value,
    storage: '1'
  }).then((res) => {
    res.result().then((rdata) => {
      variableList.value = rdata.data
      variableList.value.forEach((item) => {
        variableMap.set(item.id, item)
      })
    })
  })
}
// endregion

// region TODO 报表结构
const tableConstructionHeader = shallowRef([])
const tableConstruction = shallowRef([])
// 生成报表结构
function generateReportStructure () {
  const { device, startTime, endTime, vars } = constructionForm.value
  // 如果参数都存在
  if (device.length && startTime && endTime && vars.length) {
    const tableData = []
    try {
      // 循环设备和变量
      device.forEach((d) => {
        vars.forEach((v) => {
          // 如果大于5条数据
          if (tableData.length >= 5) {
            // 添加一条省略数据
            const item = { device: '...', var: '...', [startTime]: '...', omit: '...', [endTime]: '...' }
            tableData.splice(3, 2, item)
            throw Error() // 跳出循环
          } else {
            // 处理对象
            const item = { device: deviceMap.get(d).deviceName, var: variableMap.get(v).name, [startTime]: '——', omit: '...', [endTime]: '——' }
            tableData.push(item)
          }
        })
      })
    } catch {
      // 如果超出省略了，把最后一条添加到数组中
      const item = { device: deviceMap.get(device[device.length - 1]).deviceName, var: variableMap.get(vars[vars.length - 1]).name, [startTime]: '——', omit: '...', [endTime]: '——' }
      tableData.push(item)
    }
    // 将数据处理成垂直表格所需要的格式
    const result = TableUtil.tableDataVertical(tableData, {
      headerKey: 'device',
      headerTitle: '设备',
      props: { var: '变量', device: '设备', omit: '...' },
      headerInBody: true
    })
    tableConstructionHeader.value = result.column
    tableConstruction.value = result.tableData
  } else {
    tableConstructionHeader.value = []
    tableConstruction.value = []
  }
}
// endregion

// region TODO 生成报表
function exportReportByVar () {
  constructionFormRef.value.validate().then(() => {
    const devices = constructionForm.value.device.map(id => {
      const device = deviceMap.get(id)
      return { deviceId: device.id, deviceName: device.deviceName }
    })
    const variables = constructionForm.value.vars.map(id => {
      const variable = variableMap.get(id)
      return { url: variable.address, name: variable.name }
    })
    exportReportByVarIdsAPI({
      excelName: constructionForm.value.excelName,
      devices,
      templateId: variableTemplateId.value,
      variables,
      startTime: constructionForm.value.startTime,
      endTime: constructionForm.value.endTime
    }).then((res) => {
      res.result().then(() => {
        ElMessage.success('已生成报表，可在“导出报表”查看进度和下载')
      })
    })
  })
}
// endregion

// endregion

// region TODO 导出报表

// region TODO 查询
const searchParams = reactive({
  startTime: '',
  endTime: ''
})
function searchHandle () {
  pages.pageNum = 1
  getTableData()
}
// endregion

// region TODO 表格数据
const pages = reactive(new Pages())
const tableData = shallowRef<ExcelHistoryDTO[]>([])
const tableDataRef = shallowRef<InstanceType<typeof ElTable>>()
function getTableData () {
  const loading = ElLoading.service()
  getExportReportListByPageAPI({
    ...pages.getParams(),
    param: searchParams
  }).then((res) => {
    res.result().then((rdata) => {
      tableData.value = rdata.records
      pages.total = rdata.total
    })
  }).finally(loading.close)
}
// endregion

// endregion

</script>

<template>
  <div class="layout_view d-flex" style="min-height: 100%">
    <div class="c_card-page w-100 pt-8">
      <el-tabs v-model="activeName">
        <el-tab-pane name="Custom" label="自定义报表">
          <div style="padding: 30px 24px;">
            <el-form ref="constructionFormRef" class="c_form-save" :model="constructionForm" :rules="constructionFormRules">
              <el-form-item label="报表名称" prop="excelName">
                <el-input v-model="constructionForm.excelName" placeholder="请输入报表名称" />
              </el-form-item>
              <el-form-item label="选择设备" prop="device">
                <el-select v-model="constructionForm.device" multiple @change="deviceChangeHandle">
                  <el-option
                    v-for="item in deviceList" :key="item.id" :label="item.deviceName"
                    :value="item.id"
                    :disabled="variableTemplateId && variableTemplateId !== item.templateId"
                  >
                    <div class="d-flex-between-center">
                      <span>{{ item.deviceName }}</span>
                      <span class="text-color-placeholder fs-12">{{ item.templateName }}</span>
                    </div>
                  </el-option>
                </el-select>
              </el-form-item>
              <el-form-item label="数据时间" prop="startTime">
                <yk-date-picker
                  v-model:start="constructionForm.startTime" v-model:end="constructionForm.endTime" type="datetimerange"
                  :days="90"
                  @change="generateReportStructure"
                />
              </el-form-item>
              <el-form-item label="数据维度" prop="vars">
                <div class="bor-divider p-3" style="width: 920px;">
                  <el-checkbox-group v-model="constructionForm.vars" @change="variableChangeHandle">
                    <el-checkbox v-for="item in variableList" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox>
                  </el-checkbox-group>
                  <p v-if="!variableList.length" class="c_form-tip">请选择设备</p>
                </div>
              </el-form-item>
              <el-form-item label="报表结构">
                <div>
                  <p class="text-color-primary fs-14">报表结构仅对报表数据框架进行展示，详细数据请至“导出报表”页面导出报表查看</p>
                  <el-table :data="tableConstruction" class="mt-12 c_table-vertical" :show-header="false" empty-text="请选择完整的参数">
                    <el-table-column
                      v-for="(item, index) in tableConstructionHeader" :key="index" :prop="item.prop"
                      width="160px"
                    />
                  </el-table>
                  <el-button :icon="Download as any" type="primary" style="margin-top: 60px;" @click="exportReportByVar">生成报表</el-button>
                </div>
              </el-form-item>
            </el-form>
          </div>
        </el-tab-pane>
        <el-tab-pane name="Export" label="导出报表">
          <!--搜索表单-->
          <el-form inline class="c_form-search" @submit.prevent="searchHandle">
            <el-form-item>
              <yk-date-picker
                v-model:start="searchParams.startTime" v-model:end="searchParams.endTime"
                value-format="YYYY-MM-DD HH:mm:ss" clearable
                type="daterange"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="searchHandle">查询</el-button>
            </el-form-item>
          </el-form>
          <!--表格-->
          <el-table ref="tableDataRef" :data="tableData" class="c_table-page">
            <el-table-column label="#" type="index" />
            <el-table-column label="设备">
              <template #default="scope">
                <div class="overflow-line-clamp-2" :title="scope.row.dataSource">{{ scope.row.dataSource }}</div>
              </template>
            </el-table-column>
            <el-table-column label="数据时间">
              <template #default="scope">{{ `${scope.row.startTime} ~ ${scope.row.endTime}` }}</template>
            </el-table-column>
            <el-table-column label="数据维度">
              <template #default="scope">
                <div class="overflow-line-clamp-2" :title="scope.row.dataRadius">{{ scope.row.dataRadius }}</div>
              </template>
            </el-table-column>
            <el-table-column label="操作">
              <template #default="scope">
                <el-link v-if="scope.row.status === '2'" :href="settings.URL.IMAGE_PREFIX + scope.row.url" type="primary">
                  <span class="color-primary">下载</span>
                </el-link>
                <span v-else>{{ {0: '未开始', 1: '生成中', 3: '生成失败'}[scope.row.status] }}</span>
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <el-affix target=".c_table-page" position="bottom" :offset="0">
            <yk-pagination class="c_table-pagination-page" :pages="pages" @handle="getTableData" />
          </el-affix>
        </el-tab-pane>
      </el-tabs>
    </div>
  </div>
</template>

<style scoped lang="scss">
</style>
